package com.inesv.api.workers;

import com.alibaba.fastjson.JSONObject;
import com.inesv.api.baseclasses.BaseApi;
import com.inesv.api.baseclasses.BaseRpcSend;
import com.inesv.api.interfaces.BitMethodDefine;
import com.inesv.api.network.DefaultRPCSend;
import com.inesv.api.utils.HexUtil;
import com.inesv.api.utils.ValidateUtil;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * create by liukeling
 * class name BitApi
 * 比特币钱包rpcapi的实现类
 */
public class BitApi extends BaseApi implements BitMethodDefine {
    /**
     * 基础的构造函数  传递了钱包服务器的相关信息
     *
     * @param netRPCDefine rpc连接方式
     */
    public BitApi(BaseRpcSend netRPCDefine) {
        super(netRPCDefine);
    }

    /**
     * 根据钱包节点rpc信息创建一个以默认rpc请求方式的api
     * @param nodeRPCIp
     * @param nodeRPCPort
     * @param nodeRPCUser
     * @param nodeRPCPassword
     */
    public BitApi(String nodeRPCIp,String nodeRPCPort,String nodeRPCUser,String nodeRPCPassword){
        super(new DefaultRPCSend(nodeRPCIp,nodeRPCPort,nodeRPCUser,nodeRPCPassword));
    }

    /**
     * 传递了rpc请求方式 和初始化参数
     * @param netRPCDefine
     * @param wei
     * @param gas
     * @param gasPrice
     */
    public BitApi(BaseRpcSend netRPCDefine, BigDecimal wei,BigDecimal gas,BigDecimal gasPrice){
        super(netRPCDefine);
        this.WEI = wei;
        this.gas = gas;
        this.gasPrice = gasPrice;
    }

    /**
     * 根据钱包信息创建默认的rpc请求方式，并设置了参数初始值
     * @param nodeRPCIp
     * @param nodeRPCPort
     * @param nodeRPCUser
     * @param nodeRPCPassword
     * @param wei
     * @param gas
     * @param gasPrice
     */
    public BitApi(String nodeRPCIp,String nodeRPCPort,String nodeRPCUser,String nodeRPCPassword, BigDecimal wei,BigDecimal gas,BigDecimal gasPrice){
        super(new DefaultRPCSend(nodeRPCIp,nodeRPCPort,nodeRPCUser,nodeRPCPassword));
        this.WEI = wei;
        this.gas = gas;
        this.gasPrice = gasPrice;
    }
    @Override
    protected void initParam() {
        this.WEI = new BigDecimal("100000000");
        this.gas = null;
        this.gasPrice = null;
    }
    /**
     * 获取节点高度
     * @return  返回节点高度
     */
    @Override
    public String getHeight() {
        String responseBody = getRPCResult("getblockcount");
        return getRespponseResult(responseBody);
    }

    @Override
    public String sendTransaction(String to, String value) {
        //解锁账号
        closeWallet();
        openWallet();
        //转账
        BigDecimal sendValue = new BigDecimal(HexUtil.toTenHex(value)).divide(WEI);
        String responseBody = getRPCResult("sendtoaddress",to,sendValue);
        //关闭账号
        closeWallet();
        return getRespponseResult(responseBody);
    }

    @Override
    public String getBalance(String address) {
        String responseBody = getRPCResult("getbalance",address);
        String balance = getRPCResult(responseBody);
        if(ValidateUtil.isNull(balance)){
            return "";
        }
        BigDecimal toWei = new BigDecimal(balance).multiply(WEI);
        return HexUtil.toSixTeenHex(toWei.setScale(0,BigDecimal.ROUND_DOWN).toString());
    }
    public String getBalance(){
        String responseBody = getRPCResult("getbalance");
        String balance = getRPCResult(responseBody);
        if(ValidateUtil.isNull(balance)){
            return "";
        }
        BigDecimal toWei = new BigDecimal(balance).multiply(WEI);
        return HexUtil.toSixTeenHex(toWei.setScale(0,BigDecimal.ROUND_DOWN).toString());
    }
    @Override
    public String newAddress(String flag) {
        String responseBody = getRPCResult("getnewaddress",flag);
        return getRespponseResult(responseBody);
    }

    @Override
    public String getTransactionByHash(String hash) {
        String responseBody = getRPCResult("gettransaction",hash);
        return getRespponseResult(responseBody);
    }

    @Override
    public String openWallet() {
        String responseBody = getRPCResult("walletpassphrase",netRPCDefine.getNodeRPCPassword(),600);
        return getRespponseResult(responseBody);
    }

    @Override
    public String closeWallet() {
        String responseBody = getRPCResult("walletlock");
        return getRespponseResult(responseBody);
    }

    @Override
    public String getBlock(String hash) {
        String responseBody = getRPCResult("getblock",hash);
        return getRespponseResult(responseBody);
    }

    @Override
    public String getBlockHash(String height) {
        String he = HexUtil.toTenHex(height);
        String responseBody = getRPCResult("getblockhash",Integer.parseInt(he));
        return getRespponseResult(responseBody);
    }

    @Override
    public String listTransaction(String name, int count, int from) {
        String resonseBody = getRPCResult("listtransactions",name,count,from);
        return getRespponseResult(resonseBody);
    }

    /**
     * 根据需要的信息，调用rpc方法，获取结果
     * @param method
     * @param params
     * @return
     */
    protected String getRPCResult(String method,Object... params){
        String requestBody = new String(netRPCDefine.prepareRequest(method,params));
        return netRPCDefine.generateRequest(requestBody,netRPCDefine.getNodeUri());
    }
    /**
     * 根据rpc返回结果获取result的json数据
     * @param rpcResponse  rpc返回结果
     * @return  结果中result的json数据
     */
    protected String getRespponseResult(String rpcResponse){
        if(!ValidateUtil.isNull(rpcResponse)){
            JSONObject jsonObject = JSONObject.parseObject(rpcResponse);
            if(jsonObject.containsKey("result")){
                return jsonObject.getString("result");
            }
        }
        return "";
    }
}
